#include<iostream>
#include<unordered_map>
#include<fstream>
#include<vector>
using namespace std;

class Solution {
private:
    //力扣需要将M = 10010 N = 5010
    const static int M = 1000,N = 1000; //点 和 边的最大值
    int nodeNum,edgeNum;
    int inDegree[M]; //入度数组
    unordered_map<int,vector<int>> Edge; //起点 + 终点集
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        nodeNum = numCourses;
        edgeNum = prerequisites.size();
        //遍历所有边
        for(int i = 0; i < prerequisites.size(); i++) {
            //起点+终点
            int s_node = prerequisites[i][1];
            int e_node = prerequisites[i][0];
            inDegree[e_node]++;
            add(s_node,e_node);
        }
        return bfs();
    }

    void add(int s_node, int e_node) {
        auto it = Edge.find(s_node);
        //创建
        if(it == Edge.end()) {
            vector<int> v;
            v.push_back(e_node);
            Edge.insert(make_pair(s_node,v));
        } else {
            it->second.push_back(e_node);
        }
    }

    bool bfs() {
        vector<int> finishNode;
        for(int i = 0; i < nodeNum; i++) {
            //找一个入度为0的节点
            int findNode = -1;
            bool isFind = false;
            for(int k = 0; k < nodeNum; k++) {
                if(inDegree[k] == 0) {
                    findNode = k;
                    inDegree[k] = -1;
                    isFind = true;
                    break;
                }
            }
            //无入度为0 退出
            if(isFind == false) {
                return false;
            }
            //完成findNode 更新入度
            finishNode.push_back(findNode);
            auto it = Edge.find(findNode);
            if(it != Edge.end()) {
                auto v = it->second;
                for(int k = 0; k < v.size(); k++) {
                    inDegree[v[k]]--;
                }
            }
        }
        cout << "finishNode:";
        for(int i = 0; i < finishNode.size(); i++) {
            cout << finishNode[i] << " ";
        }
        cout << endl;
        return true;
    }

    void showInfo() {
        cout << "info:" << endl;
        for(int i = 0; i < nodeNum; i++) {
            cout << "node:" << i << " inDegree:" << inDegree[i] << " ";
            cout << " nextNode:";
            auto it = Edge.find(i);
            if(it != Edge.end()) {
                auto v = it->second;
                for(int k = 0; k < v.size(); k++) {
                    cout << v[k] << ",";
                }
            }
            cout << endl;
        }
        
    }
};

ifstream in("in.txt");
int main() {
    int nodeNum,edgeNum;
    vector<vector<int>> pv;
    in >> nodeNum >> edgeNum;
    for(int i = 0; i < edgeNum; i++) {
        vector<int> v;
        int node,prenode;
        in >> node >> prenode;
        v.push_back(node);
        v.push_back(prenode);
        pv.push_back(v);
    }
    Solution s;
    bool ret = s.canFinish(nodeNum,pv);
    cout << ret << endl;
    // s.showInfo();
    return 0;
}